{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 简介\n",
    "在这个教程中，我们将介绍pyecharts包。  \n",
    "  \n",
    "Echarts是百度开发的一个javascript可视化脚本，他的特点在于可交互（就是你鼠标移动上去，图片可以作出相应的变化）。小旭学长在echarts gallery发布了多款图表，累计12万的浏览量，获得300+赞，可以点击[这个链接](https://gallery.echartsjs.com/explore.html?u=bd-167860219&type=work#sort=rank~timeframe=all~author=all)查看  \n",
    "echarts属于门槛比较高的一种可视化方法，需要写javascript，而javascript又是基于html网页，另外数据的处理还要用python，等于说你要熟练使用得同时会js，html，python三种语言。现在pyecharts出现了，直接在python里就可以调用生成echarts图片，大部分的图表只需要用python就可以生成，非常方便！  \n",
    "  \n",
    "相比我们之前介绍的几种画图方法，各有各的优势，小旭学长的总结如下：  \n",
    ">matplotlib：纯python出图，可批量出图，缺点是出的图片为静态图片无法交互  \n",
    "folium：主要功能是绘制地图，javascript出图可交互，坐标系为wgs84，数据不需要转坐标  \n",
    "echarts：可绘制各种图表，也能绘制地图，javascript出图可交互，但绘制地图时底图一般采用百度地图，需要转坐标系\n",
    "\n",
    "那么，我们赶紧开始学习python的pyecharts包吧！"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "最近新冠肺炎的疫情是相当的不妙。  \n",
    "小旭学长观察到，一些大型网站的疫情发布地图都是基于echarts的，那么我们基于pyecharts来实现一下数据地图可视化的操作吧  \n",
    "提供的基础数据是：\n",
    "<div class=\"alert alert-info\"><h2>提供的基础数据是：</h2><p>   \n",
    "    数据：<br>  \n",
    "    不提供，我们数据从网上抓，无中生有<br>  \n",
    "\n",
    " </p></div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 数据获取"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "很多网站都提供了疫情分布情况，数据都是公开的我们直接抓就行。这里以腾讯新闻的疫情发布链接为例，观察网络链接可以找到数据获取的访问请求"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"https://gitee.com/ni1o1/pygeo-tutorial/raw/master/resource/yiqing.png\"  style=\"width:800px\">  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "好的我们用最简单的方式把它抓下来，我们做省份的可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [],
   "source": [
    "import urllib\n",
    "import json\n",
    "url = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5'\n",
    "request = urllib.request.Request(url)\n",
    "response = urllib.request.urlopen(request)\n",
    "datajson=json.loads(response.read().decode('utf8'))\n",
    "datajson=json.loads(datajson['data'])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#数据就存放在这个变量里\n",
    "datajson"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name</th>\n",
       "      <th>children</th>\n",
       "      <th>total</th>\n",
       "      <th>today</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>湖北</td>\n",
       "      <td>[{'name': '武汉', 'total': {'confirm': 8351, 'su...</td>\n",
       "      <td>{'confirm': 16678, 'suspect': 0, 'dead': 479, ...</td>\n",
       "      <td>{'confirm': 3156, 'suspect': 0, 'dead': 65, 'h...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>浙江</td>\n",
       "      <td>[{'name': '温州', 'total': {'confirm': 364, 'sus...</td>\n",
       "      <td>{'confirm': 895, 'suspect': 0, 'dead': 0, 'hea...</td>\n",
       "      <td>{'confirm': 66, 'suspect': 0, 'dead': 0, 'heal...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>广东</td>\n",
       "      <td>[{'name': '深圳', 'total': {'confirm': 289, 'sus...</td>\n",
       "      <td>{'confirm': 870, 'suspect': 0, 'dead': 0, 'hea...</td>\n",
       "      <td>{'confirm': 73, 'suspect': 0, 'dead': 0, 'heal...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>河南</td>\n",
       "      <td>[{'name': '信阳', 'total': {'confirm': 138, 'sus...</td>\n",
       "      <td>{'confirm': 764, 'suspect': 0, 'dead': 2, 'hea...</td>\n",
       "      <td>{'confirm': 89, 'suspect': 0, 'dead': 0, 'heal...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>湖南</td>\n",
       "      <td>[{'name': '长沙', 'total': {'confirm': 164, 'sus...</td>\n",
       "      <td>{'confirm': 661, 'suspect': 0, 'dead': 0, 'hea...</td>\n",
       "      <td>{'confirm': 68, 'suspect': 0, 'dead': 0, 'heal...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  name                                           children  \\\n",
       "0   湖北  [{'name': '武汉', 'total': {'confirm': 8351, 'su...   \n",
       "1   浙江  [{'name': '温州', 'total': {'confirm': 364, 'sus...   \n",
       "2   广东  [{'name': '深圳', 'total': {'confirm': 289, 'sus...   \n",
       "3   河南  [{'name': '信阳', 'total': {'confirm': 138, 'sus...   \n",
       "4   湖南  [{'name': '长沙', 'total': {'confirm': 164, 'sus...   \n",
       "\n",
       "                                               total  \\\n",
       "0  {'confirm': 16678, 'suspect': 0, 'dead': 479, ...   \n",
       "1  {'confirm': 895, 'suspect': 0, 'dead': 0, 'hea...   \n",
       "2  {'confirm': 870, 'suspect': 0, 'dead': 0, 'hea...   \n",
       "3  {'confirm': 764, 'suspect': 0, 'dead': 2, 'hea...   \n",
       "4  {'confirm': 661, 'suspect': 0, 'dead': 0, 'hea...   \n",
       "\n",
       "                                               today  \n",
       "0  {'confirm': 3156, 'suspect': 0, 'dead': 65, 'h...  \n",
       "1  {'confirm': 66, 'suspect': 0, 'dead': 0, 'heal...  \n",
       "2  {'confirm': 73, 'suspect': 0, 'dead': 0, 'heal...  \n",
       "3  {'confirm': 89, 'suspect': 0, 'dead': 0, 'heal...  \n",
       "4  {'confirm': 68, 'suspect': 0, 'dead': 0, 'heal...  "
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#提取各省份的数据\n",
    "import pandas as pd\n",
    "provincedata = pd.DataFrame(datajson['areaTree'][0]['children'])\n",
    "provincedata.head(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>confirm</th>\n",
       "      <th>suspect</th>\n",
       "      <th>dead</th>\n",
       "      <th>heal</th>\n",
       "      <th>name</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>16678</td>\n",
       "      <td>0</td>\n",
       "      <td>479</td>\n",
       "      <td>520</td>\n",
       "      <td>湖北</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>895</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>72</td>\n",
       "      <td>浙江</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>870</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>32</td>\n",
       "      <td>广东</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>764</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>47</td>\n",
       "      <td>河南</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>661</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>37</td>\n",
       "      <td>湖南</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   confirm  suspect  dead  heal name\n",
       "0    16678        0   479   520   湖北\n",
       "1      895        0     0    72   浙江\n",
       "2      870        0     0    32   广东\n",
       "3      764        0     2    47   河南\n",
       "4      661        0     0    37   湖南"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#整理一下数据，把total里面的数据展开\n",
    "data1 = pd.DataFrame(list(provincedata['total']))\n",
    "data1['name'] = provincedata['name']\n",
    "data1.head(5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "好的，到这一步我们已经获取了数据"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 可视化"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 全国数据可视化"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "官方配置文档：[pyecharts的地理图表教程](https://pyecharts.org/#/zh-cn/geography_charts)  \n",
    "首先我们要把数据整理成echarts认识的格式，就是如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([['湖北', 16678],\n",
       "       ['浙江', 895],\n",
       "       ['广东', 870],\n",
       "       ['河南', 764],\n",
       "       ['湖南', 661],\n",
       "       ['江西', 548],\n",
       "       ['安徽', 530],\n",
       "       ['重庆', 366],\n",
       "       ['江苏', 341],\n",
       "       ['四川', 301],\n",
       "       ['山东', 298],\n",
       "       ['北京', 253],\n",
       "       ['上海', 233],\n",
       "       ['福建', 205],\n",
       "       ['黑龙江', 190],\n",
       "       ['陕西', 165],\n",
       "       ['广西', 150],\n",
       "       ['河北', 135],\n",
       "       ['云南', 122],\n",
       "       ['海南', 91],\n",
       "       ['辽宁', 81],\n",
       "       ['山西', 81],\n",
       "       ['天津', 69],\n",
       "       ['贵州', 64],\n",
       "       ['甘肃', 57],\n",
       "       ['吉林', 54],\n",
       "       ['内蒙古', 42],\n",
       "       ['宁夏', 34],\n",
       "       ['新疆', 32],\n",
       "       ['香港', 18],\n",
       "       ['青海', 17],\n",
       "       ['台湾', 11],\n",
       "       ['澳门', 10],\n",
       "       ['西藏', 1]], dtype=object)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data1[['name','confirm']].values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pyecharts import options as opts\n",
    "from pyecharts.charts import Map\n",
    "#创建echarts对象c\n",
    "c = (\n",
    "    Map()#告诉echarts这个是Map形式的图表\n",
    "    .add(\"确诊\", data1[['name','confirm']].values, \"china\")#加一个数据，这个数据名叫”确诊“，数据的地图是echarts自带的china\n",
    "    .set_global_opts(#对图表添加设置\n",
    "        title_opts=opts.TitleOpts(title='疫情地图')#设置图表的名称\n",
    "    )\n",
    ")\n",
    "#导出为html文件\n",
    "c.render('疫情地图.html')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "打开目录下的 [疫情地图.html](疫情地图.html) 文件，效果如下\n",
    "<img src=\"https://gitee.com/ni1o1/pygeo-tutorial/raw/master/resource/地图v1.png\"  style=\"width:500px\">  \n",
    "但是，我们还要在加一些美化调整，一些参数可以看[echarts官方的配置项手册](https://www.echartsjs.com/zh/option.html#title)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pyecharts import options as opts\n",
    "from pyecharts.charts import Map\n",
    "c = (\n",
    "    Map()\n",
    "    .add(\"确诊\", \n",
    "         data1[['name','confirm']].values, \n",
    "         \"china\",\n",
    "         is_roam = False,#不可鼠标缩放和平移漫游\n",
    "         zoom = 1.2,#当前视角的缩放比例\n",
    "         is_map_symbol_show = False, # 是否显示标记图形\n",
    "         label_opts = opts.LabelOpts(position = 'inside'),#标签尽量放在图形区域内\n",
    "        )\n",
    "    .set_global_opts(\n",
    "        title_opts=opts.TitleOpts(title='疫情地图'),\n",
    "        visualmap_opts=opts.VisualMapOpts(is_piecewise=True,#设定分段颜色显示\n",
    "                                          pieces=[{'min': 10000,'label':'10000人以上'}, #设定分段的值\n",
    "                                                  {'min': 1000, 'max': 9999,'label':'1000-9999人'},\n",
    "                                                  {'min': 500, 'max': 999,'label':'500-999人'},\n",
    "                                                  {'min': 100, 'max': 499,'label':'100-499人'},\n",
    "                                                  {'min': 10, 'max': 99,'label':'10-99人'},\n",
    "                                                  {'min': 1, 'max': 9,'label':'1-9人'}],\n",
    "                                           range_color=[\"#b4e0f3\",\"#70b4eb\",\"#1482e5\",\"#1c3fbf\",\"#070093\" ] #调整显示颜色\n",
    "                                         ),\n",
    "    )\n",
    ")\n",
    "c.render('疫情地图.html')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "打开目录下的 [疫情地图.html](疫情地图.html) 文件，效果如下\n",
    "<img src=\"https://gitee.com/ni1o1/pygeo-tutorial/raw/master/resource/地图2.png\"  style=\"width:500px\">  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 单个省份数据可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>confirm</th>\n",
       "      <th>suspect</th>\n",
       "      <th>dead</th>\n",
       "      <th>heal</th>\n",
       "      <th>name</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>289</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>13</td>\n",
       "      <td>深圳市</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>237</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>广州市</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>69</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>珠海市</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>49</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>佛山市</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>44</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>东莞市</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   confirm  suspect  dead  heal name\n",
       "0      289        0     0    13  深圳市\n",
       "1      237        0     0     3  广州市\n",
       "2       69        0     0     1  珠海市\n",
       "3       49        0     0     1  佛山市\n",
       "4       44        0     0     0  东莞市"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "#提取省份的数据\n",
    "province = '广东'\n",
    "guangdongdata = pd.DataFrame(provincedata[provincedata['name'] == province]['children'].iloc[0])\n",
    "#整理一下数据，把total里面的数据展开\n",
    "data2 = pd.DataFrame(list(guangdongdata['total']))\n",
    "data2['name'] = guangdongdata['name']+'市'\n",
    "data2.head(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pyecharts import options as opts\n",
    "from pyecharts.charts import Map\n",
    "c = (\n",
    "    Map()\n",
    "    .add(\"确诊\", \n",
    "         data2[['name','confirm']].values, \n",
    "         province,\n",
    "         is_roam = False,#不可鼠标缩放和平移漫游\n",
    "         zoom = 1.2,#当前视角的缩放比例\n",
    "         is_map_symbol_show = False, # 是否显示标记图形\n",
    "         label_opts = opts.LabelOpts(position = 'inside'),#标签尽量放在图形区域内\n",
    "        )\n",
    "    .set_global_opts(\n",
    "        title_opts=opts.TitleOpts(title=province+'疫情地图'),\n",
    "        visualmap_opts=opts.VisualMapOpts(is_piecewise=True,#设定分段颜色显示\n",
    "                                          pieces=[{'min': 200, 'label':'200人以上'},#设定分段的值\n",
    "                                                  {'min': 100, 'max': 199,'label':'100-199人'},\n",
    "                                                  {'min': 50, 'max': 99,'label':'50-99人'},\n",
    "                                                  {'min': 10, 'max': 49,'label':'10-49人'},\n",
    "                                                  {'min': 1, 'max': 9,'label':'1-9人'}],\n",
    "                                           range_color=[\"#b4e0f3\",\"#70b4eb\",\"#1482e5\",\"#1c3fbf\",\"#070093\" ] #调整显示颜色\n",
    "                                         ),\n",
    "    )\n",
    ")\n",
    "c.render(province+'疫情地图.html')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "打开目录下的 [广东疫情地图.html](广东疫情地图.html) 文件，效果如下\n",
    "<img src=\"https://gitee.com/ni1o1/pygeo-tutorial/raw/master/resource/广东疫情地图.png\"  style=\"width:500px\">  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 作业"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "试着绘制一下精确到地级市的地图吧～[戳这里](https://gallery.echartsjs.com/editor.html?c=x8SlkZ425)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "288px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
